#include <iostream>
#include <string>
#include <functional>
#include "../third_part/muduo/include/muduo/net/TcpClient.h"
#include "../third_part/muduo/include/muduo/net/EventLoopThread.h"
#include "../third_part/muduo/include/muduo/net/TcpConnection.h"
#include "../third_part/muduo/include/muduo/base/CountDownLatch.h"
using namespace std;


class TranslateClient {
public :
    TranslateClient(const string& serverip, int serverport) 
        :_latch(1)
        ,_client(_loopthread.startLoop(), muduo::net::InetAddress(serverip, serverport), "dict_client")
    {
        auto func_t1 = std::bind(&TranslateClient::OnConnection, this, placeholders::_1);
        _client.setConnectionCallback(func_t1);

        auto func_t2 = std::bind(&TranslateClient::OnMessage, this, placeholders::_1, placeholders::_2, placeholders::_3);


        _client.setMessageCallback(func_t2);

    }
    // 连接服务器——需要阻塞等待连接建立成功之后再返回
    void Connection() {
        _client.connect(); // 连接服务器，会立即返回
        _latch.wait(); // 阻塞等待，直到连接建立成功
    }
    // 连接建立成功的回调函数——连接建立成功之后，唤醒上面的阻塞
    void OnConnection(const muduo::net::TcpConnectionPtr& conn) {
        if (conn->connected()) {
            _latch.countDown(); // 唤醒主线程中的阻塞
            // 将连接赋值给_conn
            _conn = conn;
        } else {
            // 连接要关闭了

        }

    }
    // 收到消息时候的回调函数
    void OnMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp) {
        // 从buffer中取出数据打印
        string message = buffer->retrieveAllAsString();
        cout << "server echo# " << message << endl;

    }


    // 发送数据
    bool send(const string& message) {
        // 如果连接状态是正常的，再去发送数据
        if (_conn->connected()) {
            _conn->send(message);
            return true;
        }
        return false;
    }
private :
    muduo::CountDownLatch _latch; // 进行同步的通知
    // muduo::net::EventLoop _baseloop;
    muduo::net::EventLoopThread _loopthread;
    muduo::net::TcpClient _client;
    muduo::net::TcpConnectionPtr _conn; // 客户端对应的连接，当连接成功后就会对其进行赋值



};


int main(int argc, char* args[]) {
    if (argc != 3) {
        cout << "Usage:\n\r" << args[0] << " server_ip server_port\n" << endl;
    }
    
    string serverip = args[1];
    uint16_t serverport = stoi(args[2]);
    TranslateClient translate_client(serverip, serverport);

    translate_client.Connection(); // 连接服务器

    while (true) {
        string buffer;
        // cout << "Please Enter# " << endl;
        getline(cin, buffer);
        translate_client.send(buffer);

    }
    return 0;
}